-- Spyro game element definitions, by Tatsuru

rawset(_G, "spyro", {})

-- Just so our framework doesn't interfere in other OLDC levels
freeslot("TOL_SPYRO")

//
// Various assets
//

freeslot("MT_SPYRO_NUM", "MT_SPYRO_BASKET", "MT_SPYRO_GEMSHINE", "MT_SPYRO_BALLOON", "MT_SPYRO_POWERUP", "MT_SPYRO_FOGSPAWNER", "MT_SPYRO_FAIRYFOUNTAIN",
	"S_SPYRO_DUMMY", "S_SPYRO_BASKET",
	"SPR_BSKT", "SPR_SGTW", "SPR_SBAL")

mobjinfo[MT_SPYRO_NUM] = {
	doomednum = -1,
	spawnstate = S_INVISIBLE,
	speed = 8*FRACUNIT,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY
}

mobjinfo[MT_SPYRO_BASKET] = {
	--$Name "Basket of Gems"
	--$Sprite BSKTA1
	--$Category "Spyro Things"
	doomednum = 4050,
	spawnstate = S_SPYRO_BASKET,
	spawnhealth = 1,
	radius = 16*FRACUNIT,
	height = 42*FRACUNIT,
	flags = MF_SHOOTABLE|MF_SOLID
}

mobjinfo[MT_SPYRO_GEMSHINE] = {
	doomednum = -1,
	spawnstate = S_SPYRO_DUMMY,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY
}

mobjinfo[MT_SPYRO_BALLOON] = {
	--$Name "Balloon"
	--$Sprite SBALA0
	--$Category "Spyro Things"
	doomednum = 4051,
	spawnstate = S_SPYRO_DUMMY,
	radius = 64*FRACUNIT,
	height = 64*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY
}

mobjinfo[MT_SPYRO_POWERUP] = {
	--$Name "Spyro Elemental Powerup Gate"
	--$Sprite TVFLC0
	--$Category "Spyro Things"
	doomednum = 4052,
	spawnstate = S_SPYRO_DUMMY,
	radius = 150*FRACUNIT,
	height = 250*FRACUNIT,
	flags = MF_PAPERCOLLISION|MF_SPECIAL
}

mobjinfo[MT_SPYRO_FOGSPAWNER] = {
	--$Name "Portal Fog Spawner"
	--$Sprite DUSTA0
	--$Category "Spyro Things"
	doomednum = 4053,
	spawnstate = S_INVISIBLE,
	radius = 160*FRACUNIT,
	height = FRACUNIT,
	flags = MF_PAPERCOLLISION|MF_SCENERY
}

mobjinfo[MT_SPYRO_FAIRYFOUNTAIN] = {
	--$Name "Fairy Fountain"
	--$Sprite SGTWA0
	--$Category "Spyro Things"
	doomednum = 4054,
	spawnstate = S_INVISIBLE,
	radius = 88*FRACUNIT,
	height = FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_SCENERY
}

states[S_SPYRO_DUMMY] = {
	sprite = SPR_NULL,
	tics = -1,
	nextstate = S_SPYRO_DUMMY
}

states[S_SPYRO_BASKET] = {
	sprite = SPR_BSKT,
	tics = -1,
	nextstate = S_SPYRO_BASKET
}

//
// Sounds
//

for i = 1, 7
	freeslot("sfx_gemlt" + i)
end

freeslot("sfx_spygem", "sfx_bskbrk", "sfx_gembnc", "sfx_spxdsh", "sfx_sparkl")

sfxinfo[sfx_spygem] = {
	caption = "Gem sparkle"
}

sfxinfo[sfx_bskbrk] = {
	caption = "Basket breaking"
}

sfxinfo[sfx_gembnc] = {
	caption = "Bling"
}

sfxinfo[sfx_spxdsh] = {
	caption = "Sparx buzz"
}

sfxinfo[sfx_sparkl] = {
	caption = "Flutter"
}

for i = sfx_gemlt1, sfx_gemlt7
	sfxinfo[i].caption = "Loot"
end

for _, i in ipairs({"R", "G", "P", "Y", "M"})
	for _, j in ipairs({"GEM", "NUM"})
		freeslot("SPR_" + i + j)
	end
end

//
// Gems
//

for _, i in ipairs({"RED", "GREEN", "PURPLE", "YELLOW", "MAGENTA"})
	freeslot("MT_SPYRO_" + i + "GEM")
end

mobjinfo[MT_SPYRO_REDGEM] = {
	--$Name "Red Gem"
	--$Sprite RGEMA0
	--$Category "Spyro Things"
	doomednum = 4055,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT
}

mobjinfo[MT_SPYRO_GREENGEM] = {
	--$Name "Green Gem"
	--$Sprite GGEMA0
	--$Category "Spyro Things"
	doomednum = 4056,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT
}

mobjinfo[MT_SPYRO_PURPLEGEM] = {
	--$Name "Purple Gem"
	--$Sprite PGEMA0
	--$Category "Spyro Things"
	doomednum = 4057,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT
}

mobjinfo[MT_SPYRO_YELLOWGEM] = {
	--$Name "Yellow Gem"
	--$Sprite YGEMA0
	--$Category "Spyro Things"
	doomednum = 4058,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT
}

mobjinfo[MT_SPYRO_MAGENTAGEM] = {
	--$Name "Magenta Gem"
	--$Sprite MGEMA0
	--$Category "Spyro Things"
	doomednum = 4059,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT
}

spyro.gems = {}

local frame = {16, 16, 16, 16, 16}
local value = {1, 2, 5, 10, 25}
local sprite = {SPR_RGEM, SPR_GGEM, SPR_PGEM, SPR_YGEM, SPR_MGEM}
local numsprite = {SPR_RNUM, SPR_GNUM, SPR_PNUM, SPR_YNUM, SPR_MNUM}
local color = {SKINCOLOR_RUBY, SKINCOLOR_GREEN, SKINCOLOR_PURPLE, SKINCOLOR_GOLD, SKINCOLOR_MAGENTA}

for i, j in ipairs({MT_SPYRO_REDGEM, MT_SPYRO_GREENGEM, MT_SPYRO_PURPLEGEM, MT_SPYRO_YELLOWGEM, MT_SPYRO_MAGENTAGEM})
	mobjinfo[j].spawnstate = S_SPYRO_DUMMY
	mobjinfo[j].speed = 8*FRACUNIT
	mobjinfo[j].flags = MF_SLIDEME|MF_SPECIAL
	mobjinfo[j].deathsound = sfx_spygem

	spyro.gems[j] = {
		frames = frame[i],
		value = value[i],
		sprite = sprite[i],
		numsprite = numsprite[i],
		color = color[i]
	}
end

spyro.loot = 0

addHook("MapLoad", do
	spyro.loot = 0
end)

addHook("NetVars", function(net)
	spyro.loot = net($)
end)

//
// Sparx
//

freeslot("MT_SPARX", "MT_SPARX_WINGS", "MT_SPARX_HOME", "MT_SPARX_PARTICLE", "SPR_SPRX", "SPR_SPXW", "SPR_SPRT")

mobjinfo[MT_SPARX] = {
	doomednum = -1,
	spawnstate = S_SPYRO_DUMMY,
	spawnhealth = 3,
	speed = 8*FRACUNIT,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SHOOTABLE|MF_NOCLIPHEIGHT|MF_SLIDEME
}

mobjinfo[MT_SPARX_WINGS] = {
	doomednum = -1,
	spawnstate = S_SPYRO_DUMMY,
	speed = 8*FRACUNIT,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT
}

mobjinfo[MT_SPARX_HOME] = {
	doomednum = -1,
	spawnstate = S_SPYRO_DUMMY,
	speed = 8*FRACUNIT,
	radius = 8*FRACUNIT,
	height = 8*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY|MF_SCENERY
}

mobjinfo[MT_SPARX_PARTICLE] = {
	doomednum = -1,
	spawnstate = S_SPYRO_DUMMY,
	speed = FRACUNIT,
	radius = FRACUNIT,
	height = FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIP|MF_NOCLIPHEIGHT
}

//
// Utility functions
//

rawset(_G, "IsSpyroGem", function(type)
	for i = MT_SPYRO_REDGEM, MT_SPYRO_MAGENTAGEM
		if type == i return true end
	end

	return false
end)

rawset(_G, "HeightCheck", function(abottom, atop, bbottom, btop)
	if abottom > btop return false end
	if bbottom > atop return false end
	
	return true
end)

rawset(_G, "HomingChase", function(mo, target, speed, xoffs, yoffs, zoffs, thrust)
	xoffs = $ or 0
	yoffs = $ or 0
	zoffs = $ or 0
	
	local xthrust = thrust and xoffs or 0
	local ythrust = thrust and yoffs or 0
	local zthrust = thrust and zoffs or 0
	
	local newx = target.x + xoffs
	local newy = target.y + yoffs
	local newz = target.z + zoffs
	local dist = R_PointToDist2(0, 0, R_PointToDist2(mo.x, mo.y, newx, newy), newz - mo.z)
	
	if speed < dist
		mo.momx = FixedMul(FixedDiv(newx - mo.x, dist), speed) + xthrust
		mo.momy = FixedMul(FixedDiv(newy - mo.y, dist), speed) + ythrust
		mo.momz = FixedMul(FixedDiv(newz - mo.z, dist), speed) + zthrust
	elseif speed > dist
		mo.momx = 0
		mo.momy = 0
		mo.momz = 0
		P_TeleportMove(mo, newx, newy, newz)
		return true
	end
end)